Add a new binding signal ::backspace, bind it to the backspace key, and
authorMatthias Clasen <maclas@gmx.de>
Mon, 2 Aug 2004 05:34:08 +0000 (05:34 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Mon, 2 Aug 2004 05:34:08 +0000 (05:34 +0000)
Mon Aug  2 01:30:03 2004  Matthias Clasen  <maclas@gmx.de>

* gtk/gtktextview.[hc]:
* gtk/gtkentry.[hc]: Add a new binding signal ::backspace,
bind it to the backspace key, and make it pay attention
to the Pango backspace_deletes_character
attribute.  (#119891, Noah Levitt, patch by Theppitak
Karoonboonyanan)

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkentry.c
gtk/gtkentry.h
gtk/gtktextview.c
gtk/gtktextview.h

index 6559a9e0dc59743c3e3d9ac5b72dccf8564d4a47..975a810e0bd91cc58626b723a39d6434fb41b140 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Mon Aug  2 01:30:03 2004  Matthias Clasen  <maclas@gmx.de>
+
+       * gtk/gtktextview.[hc]: 
+       * gtk/gtkentry.[hc]: Add a new binding signal ::backspace,
+       bind it to the backspace key, and make it pay attention 
+       to the Pango backspace_deletes_character 
+       attribute.  (#119891, Noah Levitt, patch by Theppitak 
+       Karoonboonyanan)
+
 Mon Aug  2 01:02:57 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gdk/x11/gdkevents-x11.c (gdk_check_wm_state_changed): 
index 6559a9e0dc59743c3e3d9ac5b72dccf8564d4a47..975a810e0bd91cc58626b723a39d6434fb41b140 100644 (file)
@@ -1,3 +1,12 @@
+Mon Aug  2 01:30:03 2004  Matthias Clasen  <maclas@gmx.de>
+
+       * gtk/gtktextview.[hc]: 
+       * gtk/gtkentry.[hc]: Add a new binding signal ::backspace,
+       bind it to the backspace key, and make it pay attention 
+       to the Pango backspace_deletes_character 
+       attribute.  (#119891, Noah Levitt, patch by Theppitak 
+       Karoonboonyanan)
+
 Mon Aug  2 01:02:57 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gdk/x11/gdkevents-x11.c (gdk_check_wm_state_changed): 
index 6559a9e0dc59743c3e3d9ac5b72dccf8564d4a47..975a810e0bd91cc58626b723a39d6434fb41b140 100644 (file)
@@ -1,3 +1,12 @@
+Mon Aug  2 01:30:03 2004  Matthias Clasen  <maclas@gmx.de>
+
+       * gtk/gtktextview.[hc]: 
+       * gtk/gtkentry.[hc]: Add a new binding signal ::backspace,
+       bind it to the backspace key, and make it pay attention 
+       to the Pango backspace_deletes_character 
+       attribute.  (#119891, Noah Levitt, patch by Theppitak 
+       Karoonboonyanan)
+
 Mon Aug  2 01:02:57 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gdk/x11/gdkevents-x11.c (gdk_check_wm_state_changed): 
index 6559a9e0dc59743c3e3d9ac5b72dccf8564d4a47..975a810e0bd91cc58626b723a39d6434fb41b140 100644 (file)
@@ -1,3 +1,12 @@
+Mon Aug  2 01:30:03 2004  Matthias Clasen  <maclas@gmx.de>
+
+       * gtk/gtktextview.[hc]: 
+       * gtk/gtkentry.[hc]: Add a new binding signal ::backspace,
+       bind it to the backspace key, and make it pay attention 
+       to the Pango backspace_deletes_character 
+       attribute.  (#119891, Noah Levitt, patch by Theppitak 
+       Karoonboonyanan)
+
 Mon Aug  2 01:02:57 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gdk/x11/gdkevents-x11.c (gdk_check_wm_state_changed): 
index 60f5cd66d2e597d12623dc905c6d3f37d08ebef2..d82ea697afb1e751bd93296d74ebe1641df1a207 100644 (file)
@@ -82,6 +82,7 @@ enum {
   MOVE_CURSOR,
   INSERT_AT_CURSOR,
   DELETE_FROM_CURSOR,
+  BACKSPACE,
   CUT_CLIPBOARD,
   COPY_CLIPBOARD,
   PASTE_CLIPBOARD,
@@ -237,6 +238,7 @@ static void gtk_entry_insert_at_cursor   (GtkEntry        *entry,
 static void gtk_entry_delete_from_cursor (GtkEntry        *entry,
                                          GtkDeleteType    type,
                                          gint             count);
+static void gtk_entry_backspace          (GtkEntry        *entry);
 static void gtk_entry_cut_clipboard      (GtkEntry        *entry);
 static void gtk_entry_copy_clipboard     (GtkEntry        *entry);
 static void gtk_entry_paste_clipboard    (GtkEntry        *entry);
@@ -469,6 +471,7 @@ gtk_entry_class_init (GtkEntryClass *class)
   class->move_cursor = gtk_entry_move_cursor;
   class->insert_at_cursor = gtk_entry_insert_at_cursor;
   class->delete_from_cursor = gtk_entry_delete_from_cursor;
+  class->backspace = gtk_entry_backspace;
   class->cut_clipboard = gtk_entry_cut_clipboard;
   class->copy_clipboard = gtk_entry_copy_clipboard;
   class->paste_clipboard = gtk_entry_paste_clipboard;
@@ -644,6 +647,15 @@ gtk_entry_class_init (GtkEntryClass *class)
                  GTK_TYPE_DELETE_TYPE,
                  G_TYPE_INT);
 
+  signals[BACKSPACE] =
+    g_signal_new ("backspace",
+                 G_OBJECT_CLASS_TYPE (gobject_class),
+                 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                 G_STRUCT_OFFSET (GtkEntryClass, backspace),
+                 NULL, NULL,
+                 _gtk_marshal_VOID__VOID,
+                 G_TYPE_NONE, 0);
+
   signals[CUT_CLIPBOARD] =
     g_signal_new ("cut_clipboard",
                  G_OBJECT_CLASS_TYPE (gobject_class),
@@ -768,15 +780,11 @@ gtk_entry_class_init (GtkEntryClass *class)
                                G_TYPE_INT, 1);
   
   gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, 0,
-                               "delete_from_cursor", 2,
-                               G_TYPE_ENUM, GTK_DELETE_CHARS,
-                               G_TYPE_INT, -1);
+                               "backspace", 0);
 
   /* Make this do the same as Backspace, to help with mis-typing */
   gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, GDK_SHIFT_MASK,
-                                "delete_from_cursor", 2,
-                                G_TYPE_ENUM, GTK_DELETE_CHARS,
-                                G_TYPE_INT, -1);
+                               "backspace", 0);
 
   gtk_binding_entry_add_signal (binding_set, GDK_Delete, GDK_CONTROL_MASK,
                                "delete_from_cursor", 2,
@@ -2421,6 +2429,72 @@ gtk_entry_delete_from_cursor (GtkEntry       *entry,
   gtk_entry_pend_cursor_blink (entry);
 }
 
+static void
+gtk_entry_backspace (GtkEntry *entry)
+{
+  GtkEditable *editable = GTK_EDITABLE (entry);
+  gint prev_pos;
+
+  gtk_entry_reset_im_context (entry);
+
+  if (!entry->editable || !entry->visible || !entry->text)
+    return;
+
+  if (entry->selection_bound != entry->current_pos)
+    {
+      gtk_editable_delete_selection (editable);
+      return;
+    }
+
+  prev_pos = gtk_entry_move_logically(entry, entry->current_pos, -1);
+
+  if (prev_pos < entry->current_pos)
+    {
+      PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE);
+      PangoLogAttr *log_attrs;
+      gint n_attrs;
+
+      pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
+
+      if (log_attrs[prev_pos].backspace_deletes_character)
+       {
+         gchar *cluster_text;
+         gchar *normalized_text;
+          glong  len;
+
+         cluster_text = gtk_editable_get_chars (editable,
+                                                prev_pos,
+                                                entry->current_pos);
+         normalized_text = g_utf8_normalize (cluster_text,
+                                             strlen (cluster_text),
+                                             G_NORMALIZE_NFD);
+          len = g_utf8_strlen (normalized_text, -1);
+
+          gtk_editable_delete_text (editable, prev_pos, entry->current_pos);
+         if (len > 1)
+           {
+             gint pos = entry->current_pos;
+
+             gtk_editable_insert_text (editable, normalized_text,
+                                       g_utf8_offset_to_pointer (normalized_text, len - 1) - normalized_text,
+                                       &pos);
+             gtk_editable_set_position (editable, pos);
+           }
+
+         g_free (normalized_text);
+         g_free (cluster_text);
+       }
+      else
+       {
+          gtk_editable_delete_text (editable, prev_pos, entry->current_pos);
+       }
+      
+      g_free (log_attrs);
+    }
+
+  gtk_entry_pend_cursor_blink (entry);
+}
+
 static void
 gtk_entry_copy_clipboard (GtkEntry *entry)
 {
index be8b4a64460606c5f942cfdb3864f3d79ce2976d..b34ed4774861731528fac00871059768448c8cd4 100644 (file)
@@ -137,6 +137,7 @@ struct _GtkEntryClass
   void (* delete_from_cursor) (GtkEntry       *entry,
                               GtkDeleteType   type,
                               gint            count);
+  void (* backspace)          (GtkEntry       *entry);
   void (* cut_clipboard)      (GtkEntry       *entry);
   void (* copy_clipboard)     (GtkEntry       *entry);
   void (* paste_clipboard)    (GtkEntry       *entry);
@@ -146,7 +147,6 @@ struct _GtkEntryClass
   void (*_gtk_reserved1) (void);
   void (*_gtk_reserved2) (void);
   void (*_gtk_reserved3) (void);
-  void (*_gtk_reserved4) (void);
 };
 
 GType      gtk_entry_get_type                  (void) G_GNUC_CONST;
index 4728c332598bfdd6b6a35e92c89433f58ddc9b31..ea51b3560d892016543e224a00b556ddae7136d3 100644 (file)
@@ -116,6 +116,7 @@ enum
   SET_ANCHOR,
   INSERT_AT_CURSOR,
   DELETE_FROM_CURSOR,
+  BACKSPACE,
   CUT_CLIPBOARD,
   COPY_CLIPBOARD,
   PASTE_CLIPBOARD,
@@ -260,6 +261,7 @@ static void gtk_text_view_insert_at_cursor (GtkTextView           *text_view,
 static void gtk_text_view_delete_from_cursor (GtkTextView           *text_view,
                                               GtkDeleteType          type,
                                               gint                   count);
+static void gtk_text_view_backspace        (GtkTextView           *text_view);
 static void gtk_text_view_cut_clipboard    (GtkTextView           *text_view);
 static void gtk_text_view_copy_clipboard   (GtkTextView           *text_view);
 static void gtk_text_view_paste_clipboard  (GtkTextView           *text_view);
@@ -526,6 +528,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
   klass->set_anchor = gtk_text_view_set_anchor;
   klass->insert_at_cursor = gtk_text_view_insert_at_cursor;
   klass->delete_from_cursor = gtk_text_view_delete_from_cursor;
+  klass->backspace = gtk_text_view_backspace;
   klass->cut_clipboard = gtk_text_view_cut_clipboard;
   klass->copy_clipboard = gtk_text_view_copy_clipboard;
   klass->paste_clipboard = gtk_text_view_paste_clipboard;
@@ -756,6 +759,15 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  GTK_TYPE_DELETE_TYPE,
                  G_TYPE_INT);
 
+  signals[BACKSPACE] =
+    g_signal_new ("backspace",
+                 G_OBJECT_CLASS_TYPE (gobject_class),
+                 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                 G_STRUCT_OFFSET (GtkTextViewClass, backspace),
+                 NULL, NULL,
+                 _gtk_marshal_VOID__VOID,
+                 G_TYPE_NONE, 0);
+
   signals[CUT_CLIPBOARD] =
     g_signal_new ("cut_clipboard",
                  G_OBJECT_CLASS_TYPE (gobject_class),
@@ -964,15 +976,11 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                                G_TYPE_INT, 1);
   
   gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, 0,
-                               "delete_from_cursor", 2,
-                               G_TYPE_ENUM, GTK_DELETE_CHARS,
-                               G_TYPE_INT, -1);
+                               "backspace", 0);
 
   /* Make this do the same as Backspace, to help with mis-typing */
   gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, GDK_SHIFT_MASK,
-                               "delete_from_cursor", 2,
-                               G_TYPE_ENUM, GTK_DELETE_CHARS,
-                               G_TYPE_INT, -1);
+                               "backspace", 0);
 
   gtk_binding_entry_add_signal (binding_set, GDK_Delete, GDK_CONTROL_MASK,
                                "delete_from_cursor", 2,
@@ -5134,6 +5142,63 @@ gtk_text_view_delete_from_cursor (GtkTextView   *text_view,
     }
 }
 
+static void
+gtk_text_view_backspace (GtkTextView *text_view)
+{
+  GtkTextIter insert;
+  GtkTextIter start;
+  GtkTextIter end;
+
+  gtk_text_view_reset_im_context (text_view);
+
+  /* Backspace deletes the selection, if one exists */
+  if (gtk_text_buffer_delete_selection (get_buffer (text_view), TRUE,
+                                        text_view->editable))
+    return;
+
+  gtk_text_buffer_get_iter_at_mark (get_buffer (text_view),
+                                    &insert,
+                                    gtk_text_buffer_get_mark (get_buffer (text_view),
+                                                              "insert"));
+
+  start = insert;
+  end = insert;
+
+  gtk_text_iter_backward_cursor_position (&end);
+
+  if (!gtk_text_iter_equal (&start, &end))
+    {
+      gchar *cluster_text = gtk_text_iter_get_text (&start, &end);
+
+      gtk_text_buffer_begin_user_action (get_buffer (text_view));
+
+      if (gtk_text_buffer_delete_interactive (get_buffer (text_view), &start, &end,
+                                              text_view->editable))
+        {
+          gchar *normalized_text = g_utf8_normalize (cluster_text,
+                                                     strlen (cluster_text),
+                                                     G_NORMALIZE_NFD);
+          glong len = g_utf8_strlen (normalized_text, -1);
+
+          if (len > 1)
+            gtk_text_buffer_insert_interactive_at_cursor (get_buffer (text_view),
+                                                          normalized_text,
+                                                          g_utf8_offset_to_pointer (normalized_text, len - 1) - normalized_text,
+                                                          text_view->editable);
+
+          g_free (normalized_text);
+        }
+
+      gtk_text_buffer_end_user_action (get_buffer (text_view));
+
+      g_free (cluster_text);
+
+      DV(g_print (G_STRLOC": scrolling onscreen\n"));
+      gtk_text_view_scroll_mark_onscreen (text_view,
+                                          gtk_text_buffer_get_mark (get_buffer (text_view), "insert"));
+    }
+}
+
 static void
 gtk_text_view_cut_clipboard (GtkTextView *text_view)
 {
index 4041323d588b4ecfbc6b4d71272bc8a819404f9d..dca3881a2849bfa69f81248420b80a671f0b34e5 100644 (file)
@@ -189,6 +189,7 @@ struct _GtkTextViewClass
   void (* delete_from_cursor)    (GtkTextView  *text_view,
                                   GtkDeleteType type,
                                   gint          count);
+  void (* backspace)             (GtkTextView *text_view);
 
   /* cut copy paste */
   void (* cut_clipboard)   (GtkTextView *text_view);
@@ -210,7 +211,6 @@ struct _GtkTextViewClass
   void (*_gtk_reserved5) (void);
   void (*_gtk_reserved6) (void);
   void (*_gtk_reserved7) (void);
-  void (*_gtk_reserved8) (void);
 };
 
 GType          gtk_text_view_get_type              (void) G_GNUC_CONST;